package cn.edu.zime.tjh.gui;

import cn.edu.zime.tjh.client.AsyncEchoClient;
import cn.edu.zime.tjh.client.AsyncEchoUDPClient;
import cn.edu.zime.tjh.handler.EchoServerHandler;
import cn.edu.zime.tjh.handler.AsyncUDPServerHandler;
import cn.edu.zime.tjh.server.EchoServer;
import cn.edu.zime.tjh.server.AsyncEchoUDPServer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

public class UnifiedGUIApp extends Application {
    
    // 服务端组件
    private ComboBox<String> serverProtocolCombo;
    private TextArea serverLogArea;
    private TextField serverPortField;
    private Button startServerButton;
    private Button stopServerButton;
    private Label serverStatusLabel;
    private Label clientCountLabel;
    private TextField broadcastField;
    private Button broadcastButton;
    private ListView<String> clientListView;
    private TextField messageToClientField;
    private Button sendToClientButton;
    private EchoServer tcpServer;
    private AsyncEchoUDPServer udpServer;
    private Timer refreshTimer;
    private ObservableList<String> clientList;
    
    // 客户端组件
    private ComboBox<String> clientProtocolCombo;
    private TextArea clientMessageArea;
    private TextField clientInputField;
    private Button connectButton;
    private Button disconnectButton;
    private Button sendMessageButton;
    private TextField hostField;
    private TextField clientPortField;
    private Label clientStatusLabel;
    private AsyncEchoClient tcpClient;
    private AsyncEchoUDPClient udpClient;
    private boolean isConnected = false;
    private String currentServerProtocol = "TCP";
    private String currentClientProtocol = "TCP";
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("智联通途IoT通信工具");
        
        createUI(primaryStage);
        setupEventHandlers();
        startRefreshTimer();
        
        // 设置服务端日志回调
        EchoServerHandler.setLogCallback((message, type) -> {
            showServerLog(message, type);
        });
        
        primaryStage.setOnCloseRequest(e -> {
            stopServer();
            disconnect();
            if (refreshTimer != null) {
                refreshTimer.cancel();
            }
            Platform.exit();
        });
        
        primaryStage.show();
    }
    
    private void createUI(Stage primaryStage) {
        TabPane tabPane = new TabPane();
        
        // 创建服务端标签页
        Tab serverTab = new Tab("服务端管理");
        serverTab.setClosable(false);
        serverTab.setContent(createServerPane());
        
        // 创建客户端标签页
        Tab clientTab = new Tab("客户端连接");
        clientTab.setClosable(false);
        clientTab.setContent(createClientPane());
        
        tabPane.getTabs().addAll(serverTab, clientTab);
        
        Scene scene = new Scene(tabPane, 1000, 700);
        primaryStage.setScene(scene);
    }
    
    private Pane createServerPane() {
        BorderPane root = new BorderPane();
        root.setPadding(new Insets(10));
        
        // 顶部 - 服务器控制
        VBox topBox = new VBox(10);
        
        HBox serverControlBox = new HBox(10);
        
        Label protocolLabel = new Label("协议:");
        serverProtocolCombo = new ComboBox<>();
        serverProtocolCombo.getItems().addAll("TCP", "UDP");
        serverProtocolCombo.setValue("TCP");
        serverProtocolCombo.setPrefWidth(80);
        
        serverControlBox.getChildren().addAll(
            protocolLabel,
            serverProtocolCombo,
            new Label("端口:"),
            serverPortField = new TextField("8080"),
            startServerButton = new Button("启动服务器"),
            stopServerButton = new Button("停止服务器")
        );
        
        serverPortField.setPrefWidth(80);
        stopServerButton.setDisable(true);
        
        serverStatusLabel = new Label("状态: 服务器已停止");
        serverStatusLabel.setStyle("-fx-text-fill: red;");
        
        clientCountLabel = new Label("已连接客户端: 0");
        
        topBox.getChildren().addAll(serverControlBox, serverStatusLabel, clientCountLabel);
        
        // 中间 - 日志区域
        VBox centerBox = new VBox(5);
        centerBox.getChildren().addAll(
            new Label("服务器日志:"),
            serverLogArea = new TextArea()
        );
        
        serverLogArea.setEditable(false);
        serverLogArea.setPrefRowCount(15);
        serverLogArea.setWrapText(true);
        
        // 右侧 - 客户端管理和消息发送
        VBox rightBox = new VBox(10);
        rightBox.setPrefWidth(300);
        
        // 广播消息
        VBox broadcastBox = new VBox(5);
        broadcastBox.getChildren().addAll(
            new Label("广播消息:"),
            broadcastField = new TextField(),
            broadcastButton = new Button("广播给所有客户端")
        );
        broadcastButton.setDisable(true);
        
        // 客户端列表
        VBox clientBox = new VBox(5);
        clientList = FXCollections.observableArrayList();
        clientListView = new ListView<>(clientList);
        clientListView.setPrefHeight(150);
        
        clientBox.getChildren().addAll(
            new Label("已连接客户端:"),
            clientListView
        );
        
        // 设置客户端列表的初始提示
        clientListView.setPlaceholder(new Label("暂无客户端连接"));
        clientListView.setPrefHeight(120);
        
        // 发送给特定客户端
        VBox messageBox = new VBox(5);
        messageBox.getChildren().addAll(
            new Label("发送给选中客户端:"),
            messageToClientField = new TextField(),
            sendToClientButton = new Button("发送消息")
        );
        sendToClientButton.setDisable(true);
        messageToClientField.setPromptText("请先选择一个客户端");
        
        rightBox.getChildren().addAll(broadcastBox, clientBox, messageBox);
        
        root.setTop(topBox);
        root.setCenter(centerBox);
        root.setRight(rightBox);
        
        return root;
    }
    
    private Pane createClientPane() {
        VBox root = new VBox(10);
        root.setPadding(new Insets(10));
        
        // 连接配置区域
        HBox connectionBox = new HBox(10);
        
        Label clientProtocolLabel = new Label("协议:");
        clientProtocolCombo = new ComboBox<>();
        clientProtocolCombo.getItems().addAll("TCP", "UDP");
        clientProtocolCombo.setValue("TCP");
        clientProtocolCombo.setPrefWidth(80);
        
        connectionBox.getChildren().addAll(
            clientProtocolLabel,
            clientProtocolCombo,
            new Label("主机:"),
            hostField = new TextField("localhost"),
            new Label("端口:"),
            clientPortField = new TextField("8080"),
            connectButton = new Button("连接"),
            disconnectButton = new Button("断开连接")
        );
        
        hostField.setPrefWidth(120);
        clientPortField.setPrefWidth(80);
        disconnectButton.setDisable(true);
        
        // 状态标签
        clientStatusLabel = new Label("状态: 未连接");
        clientStatusLabel.setStyle("-fx-text-fill: red;");
        
        // 消息显示区域
        clientMessageArea = new TextArea();
        clientMessageArea.setEditable(false);
        clientMessageArea.setPrefRowCount(20);
        clientMessageArea.setWrapText(true);
        
        // 消息输入区域
        HBox inputBox = new HBox(10);
        clientInputField = new TextField();
        sendMessageButton = new Button("发送");
        sendMessageButton.setDisable(true);
        
        clientInputField.setPrefWidth(400);
        inputBox.getChildren().addAll(clientInputField, sendMessageButton);
        
        // 组装界面
        root.getChildren().addAll(
            connectionBox,
            clientStatusLabel,
            new Label("消息:"),
            clientMessageArea,
            new Label("输入:"),
            inputBox
        );
        
        return root;
    }
    
    private void setupEventHandlers() {
        // 服务端事件处理
        startServerButton.setOnAction(e -> startServer());
        stopServerButton.setOnAction(e -> stopServer());
        broadcastButton.setOnAction(e -> broadcastMessage());
        sendToClientButton.setOnAction(e -> sendMessageToClient());
        broadcastField.setOnAction(e -> broadcastMessage());
        messageToClientField.setOnAction(e -> sendMessageToClient());
        
        // 客户端列表选择事件
        clientListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            boolean hasSelection = newValue != null;
            sendToClientButton.setDisable(!hasSelection);
            if (hasSelection) {
                messageToClientField.setPromptText("输入要发送给 " + newValue + " 的消息");
            } else {
                messageToClientField.setPromptText("请先选择一个客户端");
            }
        });
        
        // 客户端事件处理
        connectButton.setOnAction(e -> connect());
        disconnectButton.setOnAction(e -> disconnect());
        sendMessageButton.setOnAction(e -> sendMessage());
        clientInputField.setOnAction(e -> sendMessage());
    }
    
    // ==================== 服务端方法 ====================
    
    private void startServer() {
        String portText = serverPortField.getText().trim();
        
        if (portText.isEmpty()) {
            showServerLog("请输入端口号", "错误");
            return;
        }
        
        try {
            int port = Integer.parseInt(portText);
            currentServerProtocol = serverProtocolCombo.getValue();
            
            if ("TCP".equals(currentServerProtocol)) {
                tcpServer = EchoServer.getInstance();
                
                // 在新线程中启动TCP服务器
                new Thread(() -> {
                    try {
                        tcpServer.start(port);
                    } catch (Exception ex) {
                        Platform.runLater(() -> {
                            showServerLog("TCP服务器启动失败: " + ex.getMessage(), "错误");
                            resetServerControls();
                        });
                    }
                }).start();
            } else {
                udpServer = AsyncEchoUDPServer.getInstance();
                udpServer.setLogCallback(message -> showServerLog(message, "UDP服务器"));
                
                // 在新线程中启动UDP服务器
                new Thread(() -> {
                    try {
                        udpServer.start(port);
                    } catch (Exception ex) {
                        Platform.runLater(() -> {
                            showServerLog("UDP服务器启动失败: " + ex.getMessage(), "错误");
                            resetServerControls();
                        });
                    }
                }).start();
            }
            
            Platform.runLater(() -> {
                startServerButton.setDisable(true);
                stopServerButton.setDisable(false);
                broadcastButton.setDisable(false);
                sendToClientButton.setDisable(false);
                serverPortField.setDisable(true);
                serverProtocolCombo.setDisable(true);
                serverStatusLabel.setText("状态: 服务器运行中，端口 " + port + " (" + currentServerProtocol + ")");
                serverStatusLabel.setStyle("-fx-text-fill: green;");
                showServerLog(currentServerProtocol + "服务器已在端口 " + port + " 启动", "系统");
            });
            
        } catch (NumberFormatException ex) {
            showServerLog("无效的端口号", "错误");
        }
    }
    
    private void stopServer() {
        if (tcpServer != null) {
            tcpServer.stop();
        }
        if (udpServer != null) {
            udpServer.stop();
        }
        resetServerControls();
        showServerLog("服务器已停止", "系统");
    }
    
    private void resetServerControls() {
        Platform.runLater(() -> {
            startServerButton.setDisable(false);
            stopServerButton.setDisable(true);
            broadcastButton.setDisable(true);
            sendToClientButton.setDisable(true);
        messageToClientField.setPromptText("请先选择一个客户端");
            serverPortField.setDisable(false);
            serverProtocolCombo.setDisable(false);
            serverStatusLabel.setText("状态: 服务器已停止");
            serverStatusLabel.setStyle("-fx-text-fill: red;");
            clientList.clear();
            clientCountLabel.setText("已连接客户端: 0");
        });
    }
    
    private void broadcastMessage() {
        String message = broadcastField.getText().trim();
        if (message.isEmpty()) {
            showServerLog("错误: 广播消息不能为空", "错误");
            return;
        }
        
        if ("TCP".equals(currentServerProtocol)) {
            if (tcpServer != null && tcpServer.isRunning()) {
                EchoServerHandler.broadcastMessage(message);
                showServerLog("TCP广播消息: " + message, "广播");
                broadcastField.clear();
            } else {
                showServerLog("错误: TCP服务器未运行", "错误");
            }
        } else {
            showServerLog("注意: UDP协议不支持广播功能（需要客户端地址）", "警告");
        }
    }
    
    private void sendMessageToClient() {
        String selectedClient = clientListView.getSelectionModel().getSelectedItem();
        String message = messageToClientField.getText().trim();
        
        if (selectedClient == null) {
            showServerLog("请先在客户端列表中选择一个客户端", "错误");
            messageToClientField.requestFocus();
            return;
        }
        
        if (message.isEmpty()) {
            showServerLog("请输入要发送的消息", "错误");
            messageToClientField.requestFocus();
            return;
        }
        
        if ("TCP".equals(currentServerProtocol)) {
            EchoServerHandler.sendMessageToClient(selectedClient, message);
            showServerLog("已发送给TCP客户端 " + selectedClient + ": " + message, "消息");
            messageToClientField.clear();
            messageToClientField.requestFocus();
        } else {
            showServerLog("注意: UDP协议暂不支持发送给特定客户端功能", "警告");
        }
    }
    
    private void startRefreshTimer() {
        refreshTimer = new Timer(true);
        refreshTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                Platform.runLater(() -> {
                    updateClientList();
                    updateClientCount();
                });
            }
        }, 1000, 2000); // 每2秒刷新一次
    }
    
    private void updateClientList() {
        if ("TCP".equals(currentServerProtocol)) {
            if (tcpServer != null && tcpServer.isRunning()) {
                String[] clients = EchoServerHandler.getAllClientIds();
                clientList.clear();
                clientList.addAll(clients);
            }
        } else {
            if (udpServer != null && udpServer.isRunning()) {
                Set<String> clients = AsyncUDPServerHandler.getClients().keySet();
                clientList.clear();
                clientList.addAll(clients);
            }
        }
    }
    
    private void updateClientCount() {
        int count = EchoServerHandler.getClientCount();
        clientCountLabel.setText("已连接客户端: " + count);
    }
    
    public void showServerLog(String message, String type) {
        Platform.runLater(() -> {
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
            String formattedMessage = String.format("[%s] %s: %s\n", timestamp, type, message);
            serverLogArea.appendText(formattedMessage);
        });
    }
    
    // ==================== 客户端方法 ====================
    
    private void connect() {
        String host = hostField.getText().trim();
        String portText = clientPortField.getText().trim();
        
        if (host.isEmpty() || portText.isEmpty()) {
            showClientMessage("请输入主机和端口", "错误");
            return;
        }
        
        try {
            int port = Integer.parseInt(portText);
            currentClientProtocol = clientProtocolCombo.getValue();
            
            if ("TCP".equals(currentClientProtocol)) {
                // 创建异步TCP客户端
                tcpClient = new AsyncEchoClient(
                    this::handleReceivedMessage,
                    this::handleStatusMessage
                );
                
                // 在新线程中连接
                new Thread(() -> {
                    try {
                        tcpClient.connect(host, port);
                        
                        Platform.runLater(() -> {
                            isConnected = true;
                            connectButton.setDisable(true);
                            disconnectButton.setDisable(false);
                            sendMessageButton.setDisable(false);
                            hostField.setDisable(true);
                            clientPortField.setDisable(true);
                            clientProtocolCombo.setDisable(true);
                            clientStatusLabel.setText("状态: 已连接到 " + host + ":" + port + " (TCP)");
                            clientStatusLabel.setStyle("-fx-text-fill: green;");
                            showClientMessage("已连接到TCP服务器", "系统");
                        });
                        
                        // 等待连接断开
                        tcpClient.waitForDisconnection();
                        
                    } catch (Exception ex) {
                        Platform.runLater(() -> {
                            showClientMessage("TCP连接失败: " + ex.getMessage(), "错误");
                            resetConnectionState();
                        });
                    }
                }).start();
            } else {
                // 创建异步UDP客户端
                udpClient = new AsyncEchoUDPClient(
                    this::handleReceivedMessage,
                    this::handleStatusMessage
                );
                
                // 在新线程中连接
                new Thread(() -> {
                    try {
                        udpClient.connect(host, port);
                        
                        Platform.runLater(() -> {
                            isConnected = true;
                            connectButton.setDisable(true);
                            disconnectButton.setDisable(false);
                            sendMessageButton.setDisable(false);
                            hostField.setDisable(true);
                            clientPortField.setDisable(true);
                            clientProtocolCombo.setDisable(true);
                            clientStatusLabel.setText("状态: 已连接到 " + host + ":" + port + " (UDP)");
                            clientStatusLabel.setStyle("-fx-text-fill: green;");
                            showClientMessage("已连接到UDP服务器", "系统");
                        });
                        
                        // UDP连接建立后保持活跃状态
                         // UDP是无连接协议，不需要等待断开连接
                        
                    } catch (Exception ex) {
                        Platform.runLater(() -> {
                            showClientMessage("UDP连接失败: " + ex.getMessage(), "错误");
                            resetConnectionState();
                        });
                    }
                }).start();
            }
            
        } catch (NumberFormatException ex) {
            showClientMessage("无效的端口号", "错误");
        }
    }
    
    private void disconnect() {
        if (tcpClient != null) {
            tcpClient.disconnect();
        }
        if (udpClient != null) {
            udpClient.disconnect();
        }
        resetConnectionState();
    }
    
    private void resetConnectionState() {
        Platform.runLater(() -> {
            isConnected = false;
            connectButton.setDisable(false);
            disconnectButton.setDisable(true);
            sendMessageButton.setDisable(true);
            hostField.setDisable(false);
            clientPortField.setDisable(false);
            clientProtocolCombo.setDisable(false);
            clientStatusLabel.setText("状态: 未连接");
            clientStatusLabel.setStyle("-fx-text-fill: red;");
            showClientMessage("已断开与服务器的连接", "系统");
        });
    }
    
    private void sendMessage() {
        String message = clientInputField.getText().trim();
        if (message.isEmpty()) {
            return;
        }
        
        if (!isConnected) {
            showClientMessage("未连接到服务器", "错误");
            return;
        }
        
        if ("TCP".equals(currentClientProtocol) && tcpClient != null) {
            tcpClient.sendMessage(message);
        } else if ("UDP".equals(currentClientProtocol) && udpClient != null) {
            udpClient.sendMessage(message);
        }
        showClientMessage(message, "已发送");
        clientInputField.clear();
    }
    
    private void handleReceivedMessage(String message) {
        String[] parts = message.split("\\|", 2);
        if (parts.length == 2) {
            String type = parts[0];
            String content = parts[1];
            showClientMessage(content, type);
        } else {
            showClientMessage(message, "已接收");
        }
    }
    
    private void handleStatusMessage(String status) {
        showClientMessage(status, "系统");
        
        if (status.contains("断开") || status.contains("错误") || status.contains("Disconnected") || status.contains("Error")) {
            resetConnectionState();
        }
    }
    
    public void showClientMessage(String message, String type) {
        Platform.runLater(() -> {
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
            String formattedMessage = String.format("[%s] %s: %s\n", timestamp, type, message);
            clientMessageArea.appendText(formattedMessage);
        });
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}